package com.iteaj.iot.plc.melsec;

import com.iteaj.iot.FrameworkManager;
import com.iteaj.iot.SocketMessage;
import com.iteaj.iot.client.component.TcpClientComponent;
import com.iteaj.iot.codec.adapter.LengthFieldBasedFrameMessageDecoderAdapter;
import com.iteaj.iot.event.ClientStatus;
import com.iteaj.iot.event.StatusEvent;
import com.iteaj.iot.plc.PlcTcpClient;
import com.iteaj.iot.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.util.AttributeKey;

import java.nio.ByteOrder;

/**
 * 三菱PLC基于tcp实现的客户端
 */
public class MelsecTcpClient extends PlcTcpClient {

    private static AttributeKey<Boolean> handSingle = AttributeKey.newInstance("MELSEC:HAND");

    private final MelsecModel model;

    private final byte[] handSingleMessage = new byte[]{
            0x50, 0x00, 0x00, (byte) 0xFF, (byte) 0xFF, 0x03, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x01, 0x04, 0x00, 0x00, 0x64, 0x00, 0x00, (byte) 0xA8, 0x02, 0x00
    };

    public MelsecTcpClient(TcpClientComponent clientComponent, MelsecConnectProperties config) {
        super(clientComponent, config);
        this.model = config.getModel();
    }

    @Override
    protected ChannelInboundHandler createProtocolDecoder() {
        return new LengthFieldBasedFrameMessageDecoderAdapter(ByteOrder.BIG_ENDIAN, 1024
                , 6, 2, 1, 0, true) {
                //7 2 9
                //7 2 0
                //9 2 0
               //722 726  924 623
            // 929
            @Override
            public Class<? extends SocketMessage> getMessageClass() {
                return MelsecMessage.class;
            }

            @Override
            public SocketMessage doTcpDecode(ChannelHandlerContext ctx, ByteBuf decode) {
                int readableBytes = (decode).readableBytes();
                byte[] message = new byte[readableBytes];
                (decode).readBytes(message).release();
                System.out.println("消息内容：\n"+ByteUtil.bytesToHex(message));

                    String channelId = ctx.channel().id().asShortText();
                    return new MelsecMessage(message).setChannelId(channelId);

            }
        };
    }

    @Override
    public void successCallback(ChannelFuture future) {
        // 发送PLC的握手报文
        FrameworkManager.publishEvent(new StatusEvent(MelsecTcpClient.this, ClientStatus.online, getClientComponent()));
        // 发送PLC的握手报文
//        future.channel().writeAndFlush(Unpooled.wrappedBuffer(handSingleMessage)).addListener(call -> {
//            if (call.isSuccess()) {
//                if (logger.isDebugEnabled()) {
//                    logger.debug("PLC({}) 握手请求 - 状态：{} - 报文：{}"
//                            , getName(), "成功", ByteUtil.bytesToHex(handSingleMessage));
//                }
//            } else {
//                logger.error("PLC({}) 握手请求 - 状态：{} - 报文：{}"
//                        , getName(), "失败", ByteUtil.bytesToHex(handSingleMessage));
//            }
//        });
    }

    @Override
    public MelsecConnectProperties getConfig() {
        return (MelsecConnectProperties) super.getConfig();
    }

}
